<html>
<head><meta charset="utf-8"><title>Safe usage of thread_local · t-lang/wg-unsafe-code-guidelines · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/index.html">t-lang/wg-unsafe-code-guidelines</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Safe.20usage.20of.20thread_local.html">Safe usage of thread_local</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="216333807"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Safe%20usage%20of%20thread_local/near/216333807" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Elichai Turkel <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Safe.20usage.20of.20thread_local.html#216333807">(Nov 11 2020 at 11:29)</a>:</h4>
<p>I'm trying to understand if this is safe or not: <a href="https://play.rust-lang.org/?gist=5568e43218d48148c44f8718b1d68616">https://play.rust-lang.org/?gist=5568e43218d48148c44f8718b1d68616</a><br>
On one hand, logically, it should be safe.<br>
on the other shouldn't <code>one_ref.get_increment()</code> invalidate the pointer that <code>second_ref</code> holds?</p>



<a name="216334223"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Safe%20usage%20of%20thread_local/near/216334223" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Safe.20usage.20of.20thread_local.html#216334223">(Nov 11 2020 at 11:34)</a>:</h4>
<p>I think it is fine due to the <code>UnsafeCell</code>. At least miri thinks it is fine.</p>



<a name="216334498"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Safe%20usage%20of%20thread_local/near/216334498" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Elichai Turkel <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Safe.20usage.20of.20thread_local.html#216334498">(Nov 11 2020 at 11:37)</a>:</h4>
<p>but it doesn't know later that <code>UnsafeCell</code> is used (or does miri tracks pointers that have originated from an unsafeCell?)</p>



<a name="216335172"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Safe%20usage%20of%20thread_local/near/216335172" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Safe.20usage.20of.20thread_local.html#216335172">(Nov 11 2020 at 11:44)</a>:</h4>
<p><code>UnsafeCell::get</code> returns a pointer with <code>SharedReadWrite</code> provenance. This allows mixing accesses with other <code>SharedReadWrite</code> pointers to the same location.</p>



<a name="216335290"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Safe%20usage%20of%20thread_local/near/216335290" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Safe.20usage.20of.20thread_local.html#216335290">(Nov 11 2020 at 11:45)</a>:</h4>
<p>Miri tracks a borrow stack for each memory byte. Hence the name stacked borrows.</p>
<p>(it actually merges the borrow stacks of consecutive bytes with the same stack as optimization, but that isn't observable)</p>



<a name="216343547"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Safe%20usage%20of%20thread_local/near/216343547" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Daniel Henry-Mantilla <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Safe.20usage.20of.20thread_local.html#216343547">(Nov 11 2020 at 13:12)</a>:</h4>
<p>Your example is fine in that your <code>*mut T</code> is actually a <code>&amp;'_ Cell&lt;T&gt;</code>, so Stacked-Borrows-wise, all is fine.<br>
Your example is unsound in that your <code>*mut T</code> is actually a <code>&amp;'static Cell&lt;T&gt;</code>. There is a reason thread locals have such a "weird" / inconvenient API.</p>



<a name="216345220"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Safe%20usage%20of%20thread_local/near/216345220" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Daniel Henry-Mantilla <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Safe.20usage.20of.20thread_local.html#216345220">(Nov 11 2020 at 13:28)</a>:</h4>
<p>PoC (run with Miri): <a href="https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2018&amp;gist=9deec168fb63a1b0b2369ac6d3790041">https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2018&amp;gist=9deec168fb63a1b0b2369ac6d3790041</a></p>



<a name="216346686"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Safe%20usage%20of%20thread_local/near/216346686" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Daniel Henry-Mantilla <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Safe.20usage.20of.20thread_local.html#216346686">(Nov 11 2020 at 13:41)</a>:</h4>
<p>So this is how I'd implement your abstraction instead: <a href="https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2018&amp;gist=2d377f86906b70e18cf6e3bf959a4df7">https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2018&amp;gist=2d377f86906b70e18cf6e3bf959a4df7</a></p>



<a name="216355249"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Safe%20usage%20of%20thread_local/near/216355249" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Elichai Turkel <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Safe.20usage.20of.20thread_local.html#216355249">(Nov 11 2020 at 14:52)</a>:</h4>
<p><span class="user-mention" data-user-id="232018">@Daniel Henry-Mantilla</span> hmm so the problem in your PoC is because of drop order in thread_local's?</p>



<a name="216355572"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Safe%20usage%20of%20thread_local/near/216355572" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Daniel Henry-Mantilla <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Safe.20usage.20of.20thread_local.html#216355572">(Nov 11 2020 at 14:54)</a>:</h4>
<p>Basically thread locals are / may be dropped, so they're not <code>'static</code>-forever-lasting. But due to their global nature, they can be arbitrarily forged in many places, and used in that many places, such as in destructors. And indeed destructor order is not guaranteed, so you could have somebody using your <code>ThreadLocal::get_increment</code> within a destructor of another thread-local that happens to be dropped _after_ the (<code>Unsafe</code>)<code>Cell&lt;usize&gt;</code>) thread-local <span aria-label="grimacing" class="emoji emoji-1f62c" role="img" title="grimacing">:grimacing:</span></p>



<a name="216356083"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Safe%20usage%20of%20thread_local/near/216356083" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Elichai Turkel <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Safe.20usage.20of.20thread_local.html#216356083">(Nov 11 2020 at 14:59)</a>:</h4>
<p>But the current drop order will "drop" globals without destructors last, right? (which is why you had to add <code>OnDrop2</code> that also impls Drop)</p>



<a name="216729566"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Safe%20usage%20of%20thread_local/near/216729566" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Safe.20usage.20of.20thread_local.html#216729566">(Nov 14 2020 at 13:38)</a>:</h4>
<p><span class="user-mention silent" data-user-id="249222">Elichai Turkel</span> <a href="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/Safe.20usage.20of.20thread_local/near/216356083">said</a>:</p>
<blockquote>
<p>But the current drop order will "drop" globals without destructors last, right?</p>
</blockquote>
<p><code>thread_local!</code> uses os-specific APIs to call <code>drop</code> for thread-locals. I am not sure if there is any way to predict the order in which this happens.</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>